"""
Case Type   : 系统内部使用工具
Case Name   : 执行switchover时添加-W参数，是否显示switchover开始而不显示结束
Create At   : 2021/01/20
Owner       : opentestcase015
Description :
    1.在备机上执行switchover，与-W 结合使用
    2.执行refreshconf进行信息写入
    3.重启集群
    4.检查主备是否切换成功
    5.恢复主备状态
Expect      :
    1.在备机上执行switchover成功,提示信息为：server starting switchover，
      并无switchover完成的提示信息
    2.执行refrashconf进行信息写入成功
    3.重启集群成功
    4.检查主备状态，主备切换成功
    5.主备状态恢复成功
History     :
    Modified by lopentestcase027 2022/11/9: step1后判断主备切换成功后在进行refreshconf操作
    Modified by lopentestcase027 2022/11/25: tearDown步骤优化断言
"""

import time
import unittest
import os
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro
LOG = Logger()


class SystemInternalTools(unittest.TestCase):
    def setUp(self):
        LOG.info(f'--------{os.path.basename(__file__)} start--------')
        self.constant = Constant()
        self.PrimaryNode = Node('PrimaryDbUser')
        self.sh_primary = CommonSH('PrimaryDbUser')

    def test_system_internal_tools(self):
        LOG.info('----------若为单机环境，后续不执行，直接通过----------')
        query_cmd = f'''source {macro.DB_ENV_PATH};
            gs_om -t status --detail; '''
        LOG.info(query_cmd)
        query_msg = self.PrimaryNode.sh(query_cmd).result()
        LOG.info(query_msg)
        if 'Standby' not in query_msg:
            return '单机环境，后续不执行，直接通过'
        else:
            self.StandbyNode = Node('Standby1DbUser')
        LOG.info('-----step1:在备1上执行switchover与-W 结合使用'
                 '    expect:无switchover完成的提示信息')
        excute_cmd = f'''source {macro.DB_ENV_PATH};
            gs_ctl switchover -W -D {macro.DB_INSTANCE_PATH} -m fast ;
            '''
        LOG.info(excute_cmd)
        excute_msg = self.StandbyNode.sh(excute_cmd).result()
        LOG.info(excute_msg)
        self.assertNotIn(self.constant.SWITCHOVER_SUCCESS_MSG, excute_msg)
        loop = 1
        while True:
            LOG.info(f'---------第{loop}次查看主备状态是否切换成功----------')
            time.sleep(5)
            status_msg = self.PrimaryNode.sh(query_cmd).result()
            LOG.info(status_msg)
            self.assertTrue(len(status_msg.splitlines()) >= 10)
            loop += 1
            if 'S Primary Normal' in status_msg.splitlines()[-2]:
                break
            elif loop == 12:
                LOG.info("等待超1分钟，退出循环")
                break
        LOG.info('-----step2:在备1上进行refreshconf   expect: 成功-----')
        excute_cmd = f'''source {macro.DB_ENV_PATH};
            gs_om -t refreshconf;
            '''
        LOG.info(excute_cmd)
        excute_msg = self.StandbyNode.sh(excute_cmd).result()
        LOG.info(excute_msg)
        self.assertIn(self.constant.REFRESHCONF_SUCCESS_MSG, excute_msg)

        LOG.info('-----step3:重启集群        expect:重启成功-----')
        self.sh_primary.restart_db_cluster()
        status = self.sh_primary.get_db_cluster_status()
        self.assertTrue("Normal" in status or 'Degraded' in status)

        LOG.info('-----step4:检查主备状态    expect:主备状态切换成功-----')
        LOG.info(query_cmd)
        status_msg = self.PrimaryNode.sh(query_cmd).result()
        LOG.info(status_msg)
        self.assertTrue(len(status_msg.splitlines()) >= 10)
        self.node_msg = status_msg.splitlines()[-3].strip()
        self.assertIn('Standby', self.node_msg)

    def tearDown(self):
        LOG.info('-----step5:恢复主备状态    expect:主备状态恢复成功-----')
        status_cmd = f'''source {macro.DB_ENV_PATH};
            gs_om -t status --detail;
            '''
        LOG.info(status_cmd)
        status_msg = self.PrimaryNode.sh(status_cmd).result()
        LOG.info(status_msg)
        self.node_msg = status_msg.splitlines()[-3].strip()
        LOG.info(self.node_msg)
        if 'Standby' in self.node_msg:
            recover_cmd = f'''source {macro.DB_ENV_PATH};
                gs_ctl switchover -D {macro.DB_INSTANCE_PATH} -m fast;
                gs_om -t refreshconf;
                '''
            LOG.info(recover_cmd)
            recover_msg = self.PrimaryNode.sh(recover_cmd).result()
            LOG.info(recover_msg)
            LOG.info("再次查看主备状态")
            status = self.PrimaryNode.sh(status_cmd).result()
            self.assertTrue(len(status.splitlines()) >= 3)
            node1_msg = status.splitlines()[-3].strip()
            self.assertIn('P Primary Normal', node1_msg)
            self.assertTrue("Normal" in status or 'Degraded' in status)
        else:
            return '主备节点正常'
        LOG.info(f'--------{os.path.basename(__file__)} end--------')
